package com.example.demo.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.example.demo.common.constant.SystemConstants;
import com.example.demo.mapper.SysPermissionMapper;
import com.example.demo.mapper.SysRolePermissionMapper;
import com.example.demo.model.converter.SysPermissionConverter;
import com.example.demo.model.core.PageVo;
import com.example.demo.model.entity.SysPermission;
import com.example.demo.model.form.PermissionForm;
import com.example.demo.model.query.PermissionQuery;
import com.example.demo.model.vo.OptionVO;
import com.example.demo.model.vo.PermissionVO;
import com.example.demo.service.SysPermissionService;
import com.mybatisflex.core.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class SysPermissionServiceImpl implements SysPermissionService {

    @Autowired
    SysPermissionMapper sysPermissionMapper;
    @Autowired
    SysRolePermissionMapper sysRolePermissionMapper;
    @Autowired
    SysPermissionConverter sysPermissionConverter;

    @Override
    public void add(PermissionForm form) {
        SysPermission entity = sysPermissionConverter.toEntity(form);
        if (StrUtil.isBlank(form.getPid())) {
            entity.setPid(SystemConstants.ROOT_NODE);
        }
        sysPermissionMapper.insert(entity);
    }

    @Override
    public void update(PermissionForm form) {
        SysPermission entity = sysPermissionConverter.toEntity(form);
        sysPermissionMapper.update(entity);
    }

    @Override
    @Transactional
    public void delete(List<String> ids) {

        QueryWrapper wrapper = QueryWrapper.create().in("pid", ids);
        long count = sysPermissionMapper.selectCountByQuery(wrapper);
        Assert.isFalse(count > 0, "请先删除子级菜单");

        sysPermissionMapper.deleteBatchByIds(ids);
        wrapper = QueryWrapper.create().in("permission_id", ids);
        sysRolePermissionMapper.deleteByQuery(wrapper);
    }

    @Override
    public PageVo<PermissionVO> page(PermissionQuery query) {
        return null;
    }

    @Override
    public List<PermissionVO> list(PermissionQuery query) {
        QueryWrapper wrapper = QueryWrapper.create();
        if (StringUtils.isNotBlank(query.getKeywords())) {
            wrapper.like("name", query.getKeywords());
        }
        List<SysPermission> sysPermissions = sysPermissionMapper.selectListByQuery(wrapper);

        // 获取所有菜单ID
        Set<String> menuIds = sysPermissions.stream().map(SysPermission::getId).collect(Collectors.toSet());

        // 获取所有父级ID
        Set<String> parentIds = sysPermissions.stream().map(SysPermission::getPid).collect(Collectors.toSet());

        // 获取根节点ID（递归的起点），即父节点ID中不包含在部门ID中的节点，注意这里不能拿顶级菜单 O 作为根节点，因为菜单筛选的时候 O 会被过滤掉
        List<String> rootIds = parentIds.stream().filter(id -> !menuIds.contains(id)).toList();

        // 使用递归函数来构建菜单树
        return rootIds.stream()
                .flatMap(rootId -> buildPermsTree(rootId, sysPermissions).stream())
                .collect(Collectors.toList());
    }



    @Override
    public List<OptionVO<String>> options(boolean onlyParent) {
        QueryWrapper wrapper = QueryWrapper.create().orderBy("ordernum");
        List<SysPermission> sysPermissions = sysPermissionMapper.selectListByQuery(wrapper);
        return buildPermOptions(SystemConstants.ROOT_NODE, sysPermissions);
    }

    @Override
    public PermissionForm form(String id) {
        SysPermission sysPermission = sysPermissionMapper.selectOneById(id);
        Assert.notNull(sysPermission,"系统权限不存在");
        return sysPermissionConverter.toForm(sysPermission);
    }

    /**
     * 递归生成菜单列表
     *
     * @param parentId 父级ID
     * @param menuList 菜单列表
     * @return 菜单列表
     */
    private List<PermissionVO> buildPermsTree(String parentId, List<SysPermission> menuList) {
        return CollectionUtil.emptyIfNull(menuList)
                .stream()
                .filter(menu -> menu.getPid().equals(parentId))
                .map(entity -> {
                    PermissionVO permVo = sysPermissionConverter.toVo(entity);
                    List<PermissionVO> children = buildPermsTree(entity.getId(), menuList);
                    permVo.setChildren(children);
                    return permVo;
                }).toList();
    }


    /**
     * 递归生成菜单下拉层级列表
     *
     * @param parentId 父级ID
     * @param menuList 菜单列表
     * @return 菜单下拉列表
     */
    private List<OptionVO<String>> buildPermOptions(String parentId, List<SysPermission> menuList) {
        List<OptionVO<String>> menuOptions = new ArrayList<>();

        for (SysPermission menu : menuList) {
            if (menu.getPid().equals(parentId)) {
                OptionVO<String> option = new OptionVO<>(menu.getId(), menu.getName());
                List<OptionVO<String>> subMenuOptions = buildPermOptions(menu.getId(), menuList);
                if (!subMenuOptions.isEmpty()) {
                    option.setChildren(subMenuOptions);
                }
                menuOptions.add(option);
            }
        }

        return menuOptions;
    }
}
